package com.ag.lzm.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.ag.bean.TbLogType;
import com.ag.bean.TbPlan;
import com.ag.bean.TbPlanAnnex;
import com.ag.bean.TbPlanKeyword;
import com.ag.bean.TbPlanStandard;
import com.ag.bean.TbPlanStep;
import com.ag.bean.TbPsContent;
import com.ag.common.AnnexPath;
import com.ag.common.EventUtil;
import com.ag.common.IDUtil;
import com.ag.common.IIDService;
import com.ag.hmk.service.impl.WordToHtmlSerImpl;
import com.ag.lzm.dao.BaseDAO;
import com.ag.lzm.dao.TbLogTypeDAO;
import com.ag.lzm.dao.TbPlanAnnexDAO;
import com.ag.lzm.dao.TbPlanDAO;
import com.ag.lzm.dao.TbPlanKeywordDAO;
import com.ag.lzm.dao.TbPlanStandardDAO;
import com.ag.lzm.dao.TbPlanStepDAO;
import com.ag.lzm.dao.TbPsContentDAO;
import com.ag.lzm.dao.TbUriDAO;
import com.ag.lzm.service.IPlanService;
import com.ag.lzm.utils.FileUtil;
import com.ag.lzm.utils.JacksonMapper;
import com.ag.lzm.utils.PlanUtils;

public class PlanServiceImpl implements IPlanService {
	// private boolean tag = false;

	private IIDService idService;
	private TbPlanDAO planDAO;
	private TbPlanKeywordDAO planKeywordDAO;
	private TbPlanAnnexDAO planAnnexDAO;

	// 9.26修改一下内容
	private TbPlanStepDAO planStepDAO;
	private TbPsContentDAO contentDAO;
	private TbLogTypeDAO logTypeDAO;

	@Resource(name = "WordToHtmlSerImpl")
	private WordToHtmlSerImpl wthsi;
	@Resource(name = "LZMTbUriDAO")
	private TbUriDAO uriDAO;
	@Resource(name = "LZMFileUtil")
	private FileUtil fileUtil;

	public void setLogTypeDAO(TbLogTypeDAO logTypeDAO) {
		this.logTypeDAO = logTypeDAO;
	}

	public void setContentDAO(TbPsContentDAO contentDAO) {
		this.contentDAO = contentDAO;
	}

	private TbPlanStandardDAO planStandardDAO;

	public void setPlanStandardDAO(TbPlanStandardDAO planStandardDAO) {
		this.planStandardDAO = planStandardDAO;
	}

	public void setPlanStepDAO(TbPlanStepDAO planStepDAO) {
		this.planStepDAO = planStepDAO;
	}

	private BaseDAO baseDAO;

	public void setBaseDAO(BaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}

	public void setPlanAnnexDAO(TbPlanAnnexDAO planAnnexDAO) {
		this.planAnnexDAO = planAnnexDAO;
	}

	@Override
	public String findCurrentBasePath() {
		return uriDAO.findById(AnnexPath.TEMP_FILE_PATH).getUPath();
	}

	private String findPlanDiskPath() {
		return uriDAO.findById(AnnexPath.PLAN_ANNEX_PATH).getUPath();
	}

	@Override
	public List<TbPlan> findAllPlan(Map<String, String> queryOption,
			String planStatus, int firstRow, int maxRow,
			Map<String, Object> session) throws Exception {
		StringBuilder hsql = new StringBuilder();
		hsql.append("from TbPlan p join fetch p.tbPlanGrade ");
		hsql.append("join fetch p.tbPlanScope join fetch p.tbPlanRegion ");
		hsql.append("join fetch p.tbPlanStatus join fetch p.tbEventType ");
		hsql.append("join fetch p.tbPlanType where p.a = ");
		String sql = spliceHQL(checkPlanStatus(hsql, planStatus), queryOption)
				.toString();
		System.out.println("queryString11" + sql);
		if (PlanUtils.MATCHPLAN.equals(planStatus)) {
			return matchPlan(session, sql);
		} else {
			// StringBuilder hsql = new StringBuilder();
			// hsql.append("from TbPlan p join fetch p.tbPlanGrade ");
			// hsql.append("join fetch p.tbPlanScope join fetch p.tbPlanRegion ");
			// hsql.append("join fetch p.tbPlanStatus join fetch p.tbEventType ");
			// hsql.append("join fetch p.tbPlanType where p.a = ");
			// String sql = spliceHQL(checkPlanStatus(hsql, planStatus),
			// queryOption).append(" order by p.PId").toString();
			System.out.println("queryString112" + sql);
			System.out.println("////" + sql);
			return planDAO.find(sql + " order by p.PId", firstRow, maxRow);

		}
	}

	/**
	 * 匹配预案内容
	 * 
	 * @param session
	 * @return
	 */
	private List<TbPlan> matchPlan(Map<String, Object> session, String sql) {
		// String queryString =
		// "select top 3 p from TbPlan p join fetch p.tbPlanGrade pg where "
		// +
		// "pg.pgDetail = (select el.c from TbEvent e join fetch e.tbEventLevel el where e.EId = ?))";
		// String queryString="select p ";
		// queryString+=sql;
		String queryString = sql;
		queryString += " and p.tbPlanGrade.pgDetail = (select el.c from TbEvent e join e.tbEventLevel el where e.EId = ?) and p.b = "
				+ PlanUtils.RELEASE;
		System.out.println("queryString" + queryString);
		return baseDAO.find(queryString, session
				.get(EventUtil.PROCESSING_EVENT_ID));
	}

	// /**
	// * 匹配预案条数
	// *
	// * @param session
	// * @return
	// */
	// private Long matchPlanRC(Map<String, Object> session) {
	// // String queryString =
	// "select count(*) from TbPlan p join p.tbEventType pe join p.tbPlanGrade pg where "
	// // +
	// "pg.pgDetail = (select el.c from TbEvent e join e.tbEventLevel el where e.EId = ?) and pe = (select ee from TbEvent e join e.tbEventType ee where e.EId = ?)";
	// // return (Long) baseDAO.find(queryString,
	// // session.get(EventUtil.PROCESSING_EVENT_ID)).get(0);
	// String queryString =
	// "select count(*) from TbPlan p join p.tbEventType pe join p.tbPlanGrade pg where "
	// +
	// "pe.etId = (select ee.etId from TbEvent e join e.tbEventType ee where e.EId = ?) and pg.pgDetail = (select el.c from TbEvent e join e.tbEventLevel el where e.EId = ?)";
	// }

	/**
	 * 内部方法，拼接HQL
	 * 
	 * @param hsql
	 * @param planStatus
	 * @return
	 */
	private StringBuilder checkPlanStatus(StringBuilder hsql, String planStatus) {
		hsql.append(IDUtil.PRESERVE);
		if (PlanUtils.MATCHPLAN.equals(planStatus)) {
			return hsql;
		}
		hsql.append(" and p.b = ");
		if (PlanUtils.PASSORRLE.equals(planStatus)) {
			hsql.append(PlanUtils.REPORTPASS);
			hsql.append(" or p.b = ");
			hsql.append(PlanUtils.RELEASE);
		} else {
			hsql.append(planStatus);
		}
		return hsql;
	}

	@Override
	public Long findAllPlanRC(Map<String, String> queryOption,
			String planStatus, Map<String, Object> session) {
		StringBuilder hsql = new StringBuilder();
		if (PlanUtils.MATCHPLAN.equals(planStatus)) {
			String queryString = "select count(*) from TbPlan p join p.tbEventType pe join p.tbPlanGrade pg where "
					+ "pe.etId = (select ee.etId from TbEvent e join e.tbEventType ee where e.EId = ?) and pg.pgDetail = (select el.c from TbEvent e join e.tbEventLevel el where e.EId = ?) and p.b = "
					+ PlanUtils.RELEASE;
			// return matchPlanRC(session);
			// return (Long) planDAO.find(
			// spliceHQL(
			// checkPlanStatus(hsql.append(queryString),
			// planStatus), queryOption).toString())
			// .get(0);
			Object[] objects = { session.get(EventUtil.PROCESSING_EVENT_ID),
					session.get(EventUtil.PROCESSING_EVENT_ID) };
			return (Long) baseDAO.find(queryString, objects).get(0);

		} else {
			hsql.append("select count(*) from TbPlan p where p.a = ");
			return (Long) planDAO.find(
					spliceHQL(checkPlanStatus(hsql, planStatus), queryOption)
							.toString()).get(0);
		}
	}

	/**
	 * 根据查询条件动态拼接HQL语句
	 * 
	 * @param hsql
	 * @param queryOption
	 * @return
	 */
	private StringBuilder spliceHQL(StringBuilder hsql,
			Map<String, String> queryOption) {
		if (queryOption.containsKey("planType")
				&& !"0".equals(queryOption.get("planType"))) {
			hsql.append(" and p.tbPlanType.ptId = ");
			hsql.append(queryOption.get("planType"));
		}
		if (queryOption.containsKey("planStatus")
				&& !"0".equals(queryOption.get("planStatus"))) {
			hsql.append(" and p.tbPlanStatus.pstId = ");
			hsql.append(queryOption.get("planStatus"));
		}
		if (queryOption.containsKey("planScope")
				&& !"0".equals(queryOption.get("planScope"))) {
			hsql.append(" and p.tbPlanScope.psId = ");
			hsql.append(queryOption.get("planScope"));
		}
		if (queryOption.containsKey("planRegion")
				&& !"0".equals(queryOption.get("planRegion"))) {
			hsql.append(" and p.tbPlanRegion.prId = ");
			hsql.append(queryOption.get("planRegion"));
		}
		if (queryOption.containsKey("planGrade")
				&& !"0".equals(queryOption.get("planGrade"))) {
			hsql.append(" and p.tbPlanGrade.pgId = ");
			hsql.append(queryOption.get("planGrade"));
		}
		if (queryOption.containsKey("planType")
				&& !"0".equals(queryOption.get("planType"))) {
			hsql.append(" and p.tbPlanType.ptId = ");
			hsql.append(queryOption.get("planType"));
		}
		if (queryOption.containsKey("planNameIP")
				&& !"".equals(queryOption.get("planNameIP"))) {
			String planNameIPCH = queryOption.get("planNameIP");
//			try {
//				planNameIPCH = new String(queryOption.get("planNameIP")
//						.getBytes("ISO-8859-1"), "UTF-8");
////				planNameIPCH = new String(planNameIPCH.getBytes("UTF-8"),
////						"gbk");
//				System.out.println("******planNameIPCH******" + planNameIPCH);
//			} catch (UnsupportedEncodingException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
			hsql.append(" and p.PName like '%");
			hsql.append(planNameIPCH);
			hsql.append("%'");
		}
		if (queryOption.containsKey("planMan")
				&& !"".equals(queryOption.get("planMan"))) {
			hsql.append(" and p.PContractor = '");
			hsql.append(queryOption.get("planMan"));
			hsql.append("'");
		}
		if (queryOption.containsKey("planVS")
				&& !"".equals(queryOption.get("planVS"))) {
			hsql.append(" and p.PVersion = ");
			hsql.append(queryOption.get("planVS"));
		}
		if (queryOption.containsKey("startTime")
				&& !"".equals(queryOption.get("startTime"))) {
			hsql.append(" and convert(varchar(100), p.PTime, 20)  >= ");
			hsql.append("convert(varchar(100), '"+queryOption.get("startTime")+"', 20)");
			//hsql.append("'");
		}
		if (queryOption.containsKey("endTime")
				&& !"".equals(queryOption.get("endTime"))) {
			hsql.append(" and convert(varchar(100), p.PTime, 20)  <= ");
			hsql.append("convert(varchar(100), '"+queryOption.get("endTime")+"', 20)");
			//hsql.append("'");
		}
		System.out.println("-/-*-*-/-*-*/-*/-*/-/-*" + hsql);
		return hsql;
	}

	public void setPlanDAO(TbPlanDAO planDAO) {
		this.planDAO = planDAO;
	}

	public void setIdService(IIDService idService) {
		this.idService = idService;
	}

	@Override
	public void delPlanById(String pid) {
		TbPlan plan = planDAO.findById(pid);
		plan.setA(IDUtil.DELETE);
		planDAO.attachDirty(plan);
	}

	@Override
	public String savePlan(TbPlan plan, String plankeywords,
			Map<String, Object> session) {
		String pidString = idService.findTablePK(IDUtil.TB_PLAN);
		plan.setPId(pidString);
		plan.setA(IDUtil.PRESERVE);
		plan.setB(PlanUtils.NOREPORT);
		planDAO.save(plan);
		String[] keywordArr = plankeywords.split("，");
		/**
		 * 保存预案关键字
		 */
		for (String kwString : keywordArr) {
			TbPlanKeyword pkw = new TbPlanKeyword();
			pkw.setPkId(idService.findTablePK(IDUtil.TB_PLAN_KEYWORD));
			pkw.setTbPlan(plan);
			pkw.setPkContent(kwString);
			planKeywordDAO.save(pkw);
		}
		// String
		// planAnnexPath=uriDAO.findById(AnnexPath.PLAN_ANNEX_PATH).getUPath();
		if (plan.getC() != null && plan.getC() != "" && !plan.getC().isEmpty()) {
			System.out.println("good good");
			System.out.println("good good getC" + plan.getC());
			String[] fileNameArr = plan.getC().split(",");
			String[] fileRealName = plan.getD().split(",");
			// for (String fnString : fileNameArr) {
			for (int i = 0; i < fileNameArr.length; i++) {
				TbPlanAnnex pa = new TbPlanAnnex();
				pa.setTbPlan(plan);
				pa.setPaId(fileNameArr[i]);
				pa.setPaName(fileNameArr[i]);
				pa.setA(IDUtil.PRESERVE);
				pa.setPaPath(fileNameArr[i]);
				pa.setPaDetail(fileRealName[i]);
				planAnnexDAO.save(pa);
				// TbPlanAnnex pa = new TbPlanAnnex();
				// pa.setTbPlan(plan);
				// pa.setPaId(plan.getC());
				// pa.setPaName(plan.getC());
				// pa.setA(IDUtil.PRESERVE);
				// pa.setPaPath(plan.getC());
				// planAnnexDAO.save(pa);
				// wthsi.wordToHtml(planAnnexPath+fileNameArr[i],
				// planAnnexPath+fileNameArr[i]);
			}
		}

		/**
		 * 保存预案附件
		 */
		/**
		 * 保存预案附件
		 */
		/*
		 * List<PlanAnnex> paList = (List<PlanAnnex>) session
		 * .get(PlanUtils.PLAN_ANNEX); if (paList != null) { for (PlanAnnex
		 * planAnnex : paList) { TbPlanAnnex pa = new TbPlanAnnex();
		 * pa.setTbPlan(plan); pa.setPaId(planAnnex.getPaId());
		 * pa.setPaName(planAnnex.getPaName()); pa.setA(IDUtil.PRESERVE);
		 * pa.setPaPath(pa.getPaId()); planAnnexDAO.save(pa); //
		 * System.out.println("planAnnex.getPaId()"+planAnnex.getPaId()); //
		 * System.out.println("planAnnex.getPaName()"+planAnnex.getPaName()); }
		 * }
		 */
		return pidString;
	}

	public void setPlanKeywordDAO(TbPlanKeywordDAO planKeywordDAO) {
		this.planKeywordDAO = planKeywordDAO;
	}

	@Override
	public void reportPreparedPlan(String pid) {
		TbPlan p = planDAO.findById(pid);
		p.setB(PlanUtils.REPORTING);
		planDAO.attachDirty(p);
	}

	/**
	 * 通过ID找预案
	 */
	@Override
	public TbPlan findPlanById(String pid, String targetURL, String basePath) {
		StringBuilder hsql = new StringBuilder();
		// hsql.append("from TbPlan p join fetch p.tbPlanGrade ");
		// hsql.append("join fetch p.tbPlanScope join fetch p.tbPlanRegion ");
		// hsql.append("join fetch p.tbPlanStatus join fetch p.tbEventType ");
		// hsql.append("join fetch p.tbPlanType where p.PId = ?");
		hsql.append("from TbPlan p join fetch p.tbPlanGrade ");
		hsql.append("join fetch p.tbPlanScope join fetch p.tbPlanRegion ");
		hsql.append("join fetch p.tbPlanStatus join fetch p.tbEventType ");
		hsql
				.append("join fetch p.tbPlanType left join fetch p.tbPlanKeywords left join fetch p.tbPlanAnnexes left join fetch p.tbPlanSteps tbps left join fetch tbps.tbPsContents pcts left join fetch pcts.tbLogType where p.PId = ?");
		TbPlan plan = (TbPlan) planDAO.find(hsql.toString(), pid).get(0);
		for (Iterator<TbPlanAnnex> iterator = plan.getTbPlanAnnexes()
				.iterator(); iterator.hasNext();) {
			TbPlanAnnex pa = (TbPlanAnnex) iterator.next();
			String org = findPlanDiskPath() + pa.getPaId();
			String dst = targetURL + findCurrentBasePath() + pa.getPaId();

			File f2 = new File(targetURL + findCurrentBasePath());
			if (!f2.exists()) {
				f2.mkdirs();
			}

			String orgHtml = findPlanDiskPath() + pa.getPaId();
			String dstHtml = targetURL + findCurrentBasePath() + pa.getPaId();

			fileUtil.copyFileOrDir(orgHtml.substring(0, orgHtml
					.lastIndexOf("."))
					+ ".html", dstHtml.substring(0, dstHtml.lastIndexOf("."))
					+ ".html");
			fileUtil.copyFileOrDir(org.substring(0, org.lastIndexOf("."))
					+ ".files", dst.substring(0, dst.lastIndexOf("."))
					+ ".files");
			pa.setC(basePath + findCurrentBasePath()
					+ pa.getPaId().substring(0, pa.getPaId().lastIndexOf("."))
					+ ".html");
		}
		return plan;
	}

	/**
	 * 审核预案
	 */
	@Override
	public void auditPlan(String PId, String planStatus, String POpinion) {
		TbPlan p = planDAO.findById(PId);
		p.setB(planStatus);
		p.setPOpinion(POpinion);
		planDAO.attachDirty(p);
	}

	/**
	 * 发布预案
	 */
	@Override
	public void releasePlan(String pid) {
		TbPlan p = planDAO.findById(pid);
		p.setB(PlanUtils.RELEASE);
		planDAO.attachDirty(p);
	}

	/**
	 * 保存预案步骤和步骤内容
	 */
	@Override
	public void savePlanSteps(String planID, String planSteps)
			throws JsonParseException, JsonMappingException, IOException {
		ObjectMapper mapper = JacksonMapper.getInstance();
		JsonNode jsonNode = mapper.readValue(planSteps, JsonNode.class);
		JsonNode nodePS = jsonNode.get("planSteps");
		Iterator<JsonNode> nodes = nodePS.getElements();
		TbPlanStep lastPS = null;
		boolean tag = false;
		while (nodes.hasNext()) {
			JsonNode obj = nodes.next();
			TbPlanStep ps = new TbPlanStep();
			ps.setTbPlan(planDAO.findById(planID));
			ps.setPsId(idService.findTablePK(IDUtil.TB_PLAN_STEP));
			ps.setPsName(obj.get("stepName").getTextValue());
			ps.setPsContent(obj.get("stepDesc").getTextValue());
			ps.setC(obj.get("stepNote").getTextValue());
			planStepDAO.save(ps);
			Iterator<JsonNode> nodes1 = obj.get("stepCnts").getElements();
			while (nodes1.hasNext()) {
				JsonNode obj1 = nodes1.next();
				TbPsContent psc = new TbPsContent();
				psc.setPscId(idService.findTablePK(IDUtil.TB_PS_CONTENT));
				TbLogType logType = logTypeDAO.findById(obj1.get("tbLogType")
						.getTextValue());
				psc.setTbLogType(logType);
				psc.setPscContent(obj1.get("pscContent").getTextValue());
				psc.setTbPlanStep(ps);
				contentDAO.save(psc);
			}
			if (tag) {
				lastPS.setTbPlanStep(ps);
				planStepDAO.attachDirty(lastPS);
			}
			if (!tag) {
				tag = true;
				ps.setA("1");
				planStepDAO.attachDirty(ps);
			}
			lastPS = ps;
		}

	}

	@Override
	public void savePlanStandard(TbPlanStandard planStandard) {
		planStandardDAO.save(planStandard);
	}
}
